const path = require('path');
const WorkerPool = require("./worker_threads");

module.exports = class WorkerPoolRun {
    //构造函数
    constructor(workerPath, numOfThreads = 4) {
        //执行文件路径(运行工程)
        this.workerPath = workerPath;
        //线程个数
        this.numOfThreads = numOfThreads;
        //初始化数据
    }
    // 执行次数及其数据(该数据为数组)
    runTask(items = []) {
        let pool = new WorkerPool(path.resolve(this.workerPath), this.numOfThreads);
        //Promise.all
        //参数：应该是一个promise组成的数组
        //返回值：当Promise.all数组中所有promise都reolve之后，在then中返回结果数组，如果抛出错误，只会返回报错的那一个
        return Promise.all(
            //在这里给items填充内容，如果在外边填充
            //用map而不是forEach的原因是，map最终会返回一个新数组
            items.map(
                //async默认返回promise，会给上边新建的空数组填充，promise元素
                async (item, i, list) => {
                    console.time(`${item.user?(item.user.transactionId+'_'+item.user.mobile)+'_':''}${i + 1}任务耗时`);
                    //console.log(item);
                    const res = await pool.run(item || i);
                    console.log(`===== 任务${item.user?(item.user.transactionId+'_'+item.user.mobile)+'_':''}${i + 1}完成:${JSON.stringify(res)} =====`);//单个输出了，那就没必要在下边all整个输出了
                    console.timeEnd(`${item.user?(item.user.transactionId+'_'+item.user.mobile)+'_':''}${i + 1}任务耗时`);
                    console.log(" ");
                    //如果不返回res,则最终结果是undefined，
                    //map()对每一个元素操作return，并返回一个新数组，需要有返回值。
                    return res;//async返回的值会被Promise.resolve包装，所以满足Promise.all的需求
                }
            ))
            .then((result) => {
                // 销毁线程池
                // console.log(`任务完成量=>${result.length}`);
                pool.destroy();
                return result;
            })
            .catch((err) => {
                //销毁线程池
                console.error(err);
                pool.destroy();
                return err;
            });
    }
}